#pragma once

#include "CMILMatrix.h"
#include "CMILMatrix4x4.h"
#include "TransformAndClipFrame.h"
class HWClip;
class CPerspectiveTransformer;

class TransformAndClipStack
{
public: 
	TransformAndClipStack(const struct XRECTF_WH &);
	TransformAndClipStack();
	virtual ~TransformAndClipStack();
	static HRESULT Create(const TransformAndClipStack * pOriginalTransformAndClipStack, TransformAndClipStack * * ppTransformAndClipStackCopy);
	void PrependTransform(const CMILMatrix & transform);
	HRESULT IntersectLocalSpaceClip(HWClip * pClip);
	HRESULT PrependProjection(const CMILMatrix4x4 * pProjection, CPerspectiveTransformer * pProjectionTransformer);
	void Reset();
	HRESULT Set(const TransformAndClipStack * pOther);
	HRESULT PushTransformsAndClips(const TransformAndClipStack * pOther);
	XBOOL Equals(const TransformAndClipStack & other);
	HRESULT TransformPrimitiveAndTryGetOptimizedClip(const struct XRECTF_WH * pPrimitiveLocalBounds, bool isTiledPrimitive, XBOOL * pWasClipped, XBOOL * pCanClipBeOptimized, struct XRECTF_WH * pOptimizedClipRect, HWClip * pWorldSpacePrimitive, const struct XRECTF_WH * pBackBufferSize);
	HRESULT GenerateGeometry(const struct XRECTF_WH & primitiveLocalBounds, XBOOL diffuse, const CMILMatrix * pLocalToBrushAtlasTransform, const CMILMatrix * pLocalToShapeAtlasTransform, XUINT32 aaLeft, XUINT32 aaTop, XUINT32 aaRight, XUINT32 aaBottom, const struct XRECTF_RB * pBrushUVBounds, XBOOL generateInteriorGeometry, XBOOL generateExteriorGeometry, XUINT32 * pVertexCount, struct CPALVertex * * ppVertices, struct XRECTF_WH * pBounds);
	void GetCombinedTransform(CMILMatrix4x4 * pCombinedTransform);
	void Get2DTransformInLeafmostProjection(CMILMatrix * p2DTransform);
	void Set2DTransformInLeafmostProjection(const CMILMatrix & transform);
	HRESULT MergeRedirectionTransforms(const TransformAndClipStack * pRedirectedWorldTransforms);
	HRESULT TransformToLocalSpace(HWClip * pWorldClip);
	XBOOL HasZeroSizedClip();
	XBOOL HasProjection();
private: 
	TransformAndClipStack & operator=(const TransformAndClipStack &);
	TransformAndClipFrame * GetFrame(XUINT32);
	TransformAndClipFrame * GetTopFrame();
	const TransformAndClipFrame * GetTopFrameConst();
	HRESULT PushFrame(TransformAndClipFrame * * ppNewFrame);
	static void CalculateAAPoints(XUINT32 cPoints, const struct PointWithAAMasks * pt3D, XUINT32 generateInteriorGeometry, XUINT32 generateExteriorGeometry, XUINT32 cPointsWithAA, struct XPOINTF4 * pPoints);
	TransformAndClipFrame m_bottomFrame;  
	xvector<TransformAndClipFrame> m_additionalFrames; 

};